<?php


namespace utils;


// use exceptions\AdminException;
// use services\CacheService;
use exceptions\ApiException;
use Firebase\JWT\JWT;
use services\CacheService;
use think\facade\Env;

/**
 * Jwt
 * Class JwtAuth
 * @package utils
 */
class JwtAuth
{

    /**
     * token
     * @var string
     */
    protected $token;

    /**
     * 获取token
     *
     * @param int    $id
     * @param string $type
     * @param array  $params
     *
     * @return array
     */
    public function getToken(int $id, string $type, array $params = []): array
    {
        $host = app()->request->host();
        $time = time();

        $params        += [
            'iss' => $host,
            'aud' => $host,
            'iat' => $time,
            'nbf' => $time,
            'exp' => $params['exp'] ?? strtotime('+ 3hour'),
        ];
        $params['jti'] = compact('id', 'type');
        $token         = JWT::encode($params, Env::get('app.app_key', 'default'));
        return compact('token', 'params');
    }

    /**
     * 解析token
     *
     * @param string $jwt
     *
     * @return array
     */
    public function parseToken(string $jwt): array
    {
        $this->token = $jwt;
        [$headb64, $bodyb64, $cryptob64] = explode('.', $this->token);
        $payload = JWT::jsonDecode(JWT::urlsafeB64Decode($bodyb64));
        return [$payload->jti->id, $payload->jti->type];
    }

    /**
     * 验证token
     */
    public function verifyToken()
    {
        JWT::$leeway = 60;

        JWT::decode($this->token, Env::get('app.app_key', 'default'), ['HS256']);

        $this->token = null;
    }

    /**
     * Description: 获取token并放入令牌桶
     *
     * @param int    $id
     * @param string $type
     * @param array  $params
     *
     * @return array
     * @throws \Psr\SimpleCache\InvalidArgumentException
     * @author: dtt
     * @date  : 2021/7/6 0006
     * @time  : 9:51
     */
    public function createToken(int $id, string $type, array $params = [])
    {
        $tokenInfo = $this->getToken($id, $type, $params);
        $exp       = $tokenInfo['params']['exp'] - $tokenInfo['params']['iat'] + 60;
        $res       = CacheService::setTokenBucket($id . '_user_token', ['uid' => $id, 'type' => $type, 'token' => $tokenInfo['token'], 'exp' => $exp], (int)$exp);
        if (!$res) {
            throw new ApiException('保存token失败');
        }
        return $tokenInfo;
    }
}
